from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func, and_, or_
from datetime import datetime
from pydantic import BaseModel

from app.core.database import get_db
from app.models.hackathon import Hackathon

router = APIRouter()


class HackathonCreate(BaseModel):
    title: str
    description: str
    type: str = "hackathon"
    platform: str
    prize_pool: Optional[str] = None
    prize_currency: str = "CNY"
    deadline: Optional[str] = None
    participants_count: int = 0
    max_participants: Optional[int] = None
    difficulty: str = "intermediate"
    category: str
    tags: Optional[List[str]] = []
    banner_image: Optional[str] = None
    external_url: Optional[str] = None
    status: str = "ongoing"


@router.get("/")
async def get_competitions(
    search: Optional[str] = Query(None, description="搜索关键词"),
    category: Optional[str] = Query(None, description="竞赛分类"),
    difficulty: Optional[str] = Query(None, description="难度等级"),
    platform: Optional[str] = Query(None, description="平台"),
    page: int = Query(1, ge=1, description="页码"),
    size: int = Query(20, ge=1, le=100, description="每页数量"),
    db: AsyncSession = Depends(get_db)
):
    """获取竞赛列表"""
    
    try:
        # 构建查询条件
        conditions = [Hackathon.status == 'ongoing']
        
        if search:
            search_condition = or_(
                Hackathon.title.ilike(f"%{search}%"),
                Hackathon.description.ilike(f"%{search}%")
            )
            conditions.append(search_condition)
        
        if category:
            conditions.append(Hackathon.category == category)
        
        if difficulty:
            conditions.append(Hackathon.difficulty == difficulty)
        
        if platform:
            conditions.append(Hackathon.platform == platform)
        
        # 执行查询
        query = select(Hackathon).where(and_(*conditions))
        
        # 排序：按截止时间排序
        query = query.order_by(Hackathon.deadline.asc())
        
        # 分页
        offset = (page - 1) * size
        query = query.offset(offset).limit(size)
        
        result = await db.execute(query)
        competitions = result.scalars().all()
        
        # 转换为前端期望的格式
        competitions_data = []
        for comp in competitions:
            competitions_data.append({
                "id": str(comp.id),
                "title": comp.title,
                "description": comp.description,
                "platform": comp.platform,
                "prize": f"{comp.prize_currency} {comp.prize_pool}" if comp.prize_pool else "待定",
                "deadline": comp.deadline.isoformat() if comp.deadline else None,
                "participants": comp.participants_count,
                "difficulty": comp.difficulty,
                "category": comp.category,
                "tags": comp.tags or [],
                "image": comp.banner_image,
                "link": comp.external_url,
                "status": comp.status
            })
        
        return {
            "success": True,
            "data": competitions_data,
            "total": len(competitions_data)
        }
        
    except Exception as e:
        print(f"Error fetching competitions: {e}")
        return {
            "success": False,
            "data": [],
            "total": 0,
            "error": str(e)
        }


@router.get("/{competition_id}")
async def get_competition(
    competition_id: str,
    db: AsyncSession = Depends(get_db)
):
    """获取竞赛详情"""
    try:
        result = await db.execute(
            select(Hackathon)
            .where(Hackathon.id == competition_id)
        )
        competition = result.scalar_one_or_none()
        
        if not competition:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Competition not found"
            )
        
        # 转换为前端期望的格式
        competition_data = {
            "id": str(competition.id),
            "title": competition.title,
            "description": competition.description,
            "platform": competition.platform,
            "prize": f"{competition.prize_currency} {competition.prize_pool}" if competition.prize_pool else "待定",
            "deadline": competition.deadline.isoformat() if competition.deadline else None,
            "participants": competition.participants_count,
            "difficulty": competition.difficulty,
            "category": competition.category,
            "tags": competition.tags or [],
            "image": competition.banner_image,
            "link": competition.external_url,
            "status": competition.status,
            "created_at": competition.created_at.isoformat() if competition.created_at else None,
            "updated_at": competition.updated_at.isoformat() if competition.updated_at else None
        }
        
        return {
            "success": True,
            "data": competition_data
        }
        
    except HTTPException:
        raise
    except Exception as e:
        print(f"Error fetching competition {competition_id}: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Internal server error: {str(e)}"
        )


@router.get("/categories/list")
async def get_categories(db: AsyncSession = Depends(get_db)):
    """获取所有竞赛分类"""
    try:
        result = await db.execute(
            select(Hackathon.category)
            .where(Hackathon.category.isnot(None))
            .distinct()
        )
        categories = [row[0] for row in result.fetchall()]
        
        return {
            "success": True,
            "data": categories
        }
    except Exception as e:
        return {
            "success": False,
            "data": [],
            "error": str(e)
        }


@router.get("/platforms/list")
async def get_platforms(db: AsyncSession = Depends(get_db)):
    """获取所有竞赛平台"""
    try:
        result = await db.execute(
            select(Hackathon.platform)
            .where(Hackathon.platform.isnot(None))
            .distinct()
        )
        platforms = [row[0] for row in result.fetchall()]
        
        return {
            "success": True,
            "data": platforms
        }
    except Exception as e:
        return {
            "success": False,
            "data": [],
            "error": str(e)
        }


@router.post("/")
async def create_competition(
    competition_data: HackathonCreate,
    db: AsyncSession = Depends(get_db)
):
    """创建新竞赛"""
    try:
        # 解析截止时间
        deadline = None
        if competition_data.deadline:
            try:
                deadline = datetime.fromisoformat(competition_data.deadline.replace('Z', '+00:00'))
            except ValueError:
                deadline = datetime.fromisoformat(competition_data.deadline)
        
        # 创建新竞赛
        new_competition = Hackathon(
            title=competition_data.title,
            description=competition_data.description,
            type=competition_data.type,
            platform=competition_data.platform,
            prize_pool=competition_data.prize_pool,
            prize_currency=competition_data.prize_currency,
            deadline=deadline,
            participants_count=competition_data.participants_count,
            max_participants=competition_data.max_participants,
            difficulty=competition_data.difficulty,
            category=competition_data.category,
            tags=competition_data.tags,
            banner_image=competition_data.banner_image,
            external_url=competition_data.external_url,
            status=competition_data.status
        )
        
        db.add(new_competition)
        await db.commit()
        await db.refresh(new_competition)
        
        # 返回创建的竞赛数据
        competition_response = {
            "id": str(new_competition.id),
            "title": new_competition.title,
            "description": new_competition.description,
            "platform": new_competition.platform,
            "prize": f"{new_competition.prize_currency} {new_competition.prize_pool}" if new_competition.prize_pool else "待定",
            "deadline": new_competition.deadline.isoformat() if new_competition.deadline else None,
            "participants": new_competition.participants_count,
            "difficulty": new_competition.difficulty,
            "category": new_competition.category,
            "tags": new_competition.tags or [],
            "image": new_competition.banner_image,
            "link": new_competition.external_url,
            "status": new_competition.status
        }
        
        return {
            "success": True,
            "data": competition_response,
            "message": "竞赛创建成功"
        }
        
    except Exception as e:
        await db.rollback()
        print(f"Error creating competition: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"创建竞赛失败: {str(e)}"
        )